package com.li.controller;


import com.li.common.ModelName;
import com.li.config.AiConfig;

import com.li.utils.IdHandle;
import com.li.utils.IdUtils;
import dev.langchain4j.community.model.dashscope.QwenChatModel;
import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel;

import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.service.TokenStream;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;


import java.io.IOException;



@RestController
@RequestMapping("/ai")
public class ChatController {

    @Resource
    QwenChatModel qwenChatModel;
    @Resource
    QwenStreamingChatModel qwenStreamingChatModel;


    // API 入口：普通聊天
    @RequestMapping("/chat")
    public String chat(@RequestParam(name = "message", defaultValue = "你好，你是谁？你擅长做什么？") String message) {
        return qwenChatModel.chat(message);
    }
    // API 入口：流式聊天
    @RequestMapping("/stream/chatv1")
    public String streamChat(
            @RequestParam(name = "message", defaultValue = "你好，你是谁？请介绍一下流式输出。") String message) throws IOException {
            qwenStreamingChatModel.chat(message, new StreamingChatResponseHandler() {
                @Override
                public void onPartialResponse(String partialResponse) {
                    //每一次流式响应的文本
                    System.out.println(partialResponse);
                }
                @Override
                public void onCompleteResponse(ChatResponse completeResponse) {
                    //响应结束的文本
                    System.out.println("结束"+completeResponse);
                }

                @Override
                public void onError(Throwable error) {
                        error.printStackTrace();
                }
            });
            return "chat-success";
        }
    //将内容响应给前端
    @RequestMapping(value = "/stream/chatv2" ,produces ="text/stream;charset=UTF-8")
        public Flux<String> streamChatWebFlux(@RequestParam(name = "message", defaultValue = "你好，你是谁？请介绍一下webFlux")String message){
        Flux<String> strFlux = Flux.create(sink -> {
            qwenStreamingChatModel.chat(message, new StreamingChatResponseHandler() {
                @Override
                public void onPartialResponse(String partialResponse) {
                    //每一次流式响应的文本
                    sink.next(partialResponse);
                }
                @Override
                public void onCompleteResponse(ChatResponse completeResponse) {
                    //响应结束的文本
                    sink.complete();
                }
                @Override
                public void onError(Throwable error) {
                    sink.error(error);
                }
            });
        });
    return strFlux;
    }

    @Resource
    IdHandle idHandle;
    @Resource(name="assistant")
    private AiConfig.Assistant assistant;
    @RequestMapping("/chat/chatMemory/{id}")
    public String memoryChat(@PathVariable(name = "id") Integer id, @RequestParam(name = "message", defaultValue = "你好，你知道射雕英雄传的郭靖吗? 请介绍一下他")
            String message)
    {
        String uid = idHandle.uidParse(id, ModelName.QWQ_32B_PREVIEW);
        return assistant.chat(uid,message);
    }
    @RequestMapping(value = "/stream/chatMemoryByStream/{id}",produces ="text/stream;charset=UTF-8")
    public Flux<String> memoryChatByStream(@PathVariable(name = "id") Integer id,@RequestParam(name = "message", defaultValue = "他都会那些绝学呢?")
                                          String message)
    {
        String uid = idHandle.uidParse(id, ModelName.QWQ_32B_PREVIEW);
        TokenStream stream = assistant.streamChat(uid,message);
        return Flux.create(sink -> {
            stream.onPartialResponse(sink::next)
                    .onCompleteResponse(response -> {
                        System.out.println(response);
                        sink.complete(); //关闭流式响应
                    })
                    .onError(sink::error)
                    .start();
        });
    }

}

